<?php

namespace admin\hooks\controller;

use cmf\controller\AdminBaseController;
use common\hooks\model\HookModel;
use common\hooks\model\PluginModel;
use common\hooks\model\HookPluginModel;
use think\Db;

/**
 * Class HookController 钩子管理控制器
 * @package app\admin\controller
 */
class HookController extends AdminBaseController {

    /**
     * 钩子管理
     * @adminMenu(
     *     'name'   => '钩子管理',
     *     'parent' => 'admin/Plugin/default',
     *     'display'=> true,
     *     'hasView'=> true,
     *     'order'  => 10000,
     *     'icon'   => '',
     *     'remark' => '钩子管理',
     *     'param'  => ''
     * )
     */
    public function index() {
        $hookModel = new HookModel();
        $hooks = $hookModel->order('type asc')->select();
        $this->assign('hooks', $hooks);
        return $this->fetch();
    }

    /**
     * 钩子插件管理
     * @adminMenu(
     *     'name'   => '钩子插件管理',
     *     'parent' => 'index',
     *     'display'=> false,
     *     'hasView'=> true,
     *     'order'  => 10000,
     *     'icon'   => '',
     *     'remark' => '钩子插件管理',
     *     'param'  => ''
     * )
     */
    public function plugins() {
        $hook = $this->request->param('hook');
        $pluginModel = new PluginModel();
        $plugins = $pluginModel->field('a.*,b.hook,b.plugin,b.list_order,b.status as hook_plugin_status,b.id as hook_plugin_id')
                ->alias('a')->join('__HOOK_PLUGIN__ b', 'a.name = b.plugin')
                ->where('b.hook', $hook)
                ->order('b.list_order asc')
                ->select();
        $this->assign('plugins', $plugins);
        return $this->fetch();
    }

    /**
     * 钩子插件排序
     * @adminMenu(
     *     'name'   => '钩子插件排序',
     *     'parent' => 'index',
     *     'display'=> false,
     *     'hasView'=> false,
     *     'order'  => 10000,
     *     'icon'   => '',
     *     'remark' => '钩子插件排序',
     *     'param'  => ''
     * )
     */
    public function pluginListOrder() {
        $hookPluginModel = new HookPluginModel();
        parent::listOrders($hookPluginModel);

        $this->success("排序更新成功！");
    }

    /**
     * 同步钩子
     * @adminMenu(
     *     'name'   => '同步钩子',
     *     'parent' => 'index',
     *     'display'=> false,
     *     'hasView'=> true,
     *     'order'  => 10000,
     *     'icon'   => '',
     *     'remark' => '同步钩子',
     *     'param'  => ''
     * )
     */
    public function sync() {

        $apps = [];
        array_push($apps, APP_COMMON);
        array_push($apps, APP_APP);
        array_push($apps, APP_PATH);
        foreach ($apps as $app) {
            $this->_sync_app($app);
        }

        // cmf 更新
        $hookConfigFile = CMF_PATH . 'hooks.php';
        $this->_sync_update($hookConfigFile);

        return $this->fetch();
    }

    // 同步指定应用的hooks
    private function _sync_app($path = APP_PATH) {
        // 扫描应用下的模块
        $apps = cmf_scan_dir($path . '*', GLOB_ONLYDIR);

        foreach ($apps as $app) {
            $hookConfigFile = $path . $app . '/hooks.php';
            $this->_sync_update($hookConfigFile,$app);
        }

        return true;
    }

    private function _sync_update($hookConfigFile = '',$app='') {
        if (file_exists($hookConfigFile)) {

            $hooksInFile = include $hookConfigFile;
            // 更新
            foreach ($hooksInFile as $hookName => $hook) {
                // 默认应用钩子
                $hook['type'] = empty($hook['type']) ? 2 : $hook['type'];

                if (!in_array($hook['type'], [2, 3, 4]) && $app != 'cmf') {
                    $hook['type'] = 2;
                }

                // 默认模块
                $hook['app'] = empty($hook['app']) ? $app : $hook['app'];

                $findHook = Db::name('hook')->where(['hook' => $hookName])->count();

                if ($findHook > 0) {
                    Db::name('hook')->where(['hook' => $hookName])->strict(false)->field(true)->update($hook);
                } else {
                    $hook['hook'] = $hookName;
                    Db::name('hook')->insert($hook);
                }
            }
        }

        return true;
    }

}
